#region License
// /* **************************************************************
// * Copyright (C) intex Consulting GmbH - All Rights Reserved    *
// *--------------------------------------------------------------*
// * Unauthorized copying of this file, via any medium is         *
// * strictly prohibited                                          *
// *--------------------------------------------------------------*
// * Proprietary and confidential                                 *
// *--------------------------------------------------------------*
// * Dissasembling/modifications strictly prohibited!             *
// ***************************************************************/
#endregion
using System;
using System.IO;
using System.Runtime.Serialization;
using System.Xml.Serialization;

namespace ComHlp.Classes
{
    /// <summary> Save (Serialize) or Load (DeSerialize) any xml file which is used from within Nyx </summary>
    public class YaSerializer
    {
        /// <summary> Serialize object to file </summary>
        /// <param name="filePath"></param>
        /// <param name="serializationObject"></param>
        /// <exception cref="SerializationException"></exception>
        public void SerializeObject<T>(string filePath, T serializationObject)
        {
            // get directory name
            string path = Path.GetDirectoryName(filePath);
            if (path != null && !Directory.Exists(path))
            {
                // create directory thu it does not exist
                try
                {
                    Directory.CreateDirectory(path);
                }
                catch (IOException exc)
                {
                    throw new SerializationException($"Unable to create directory {path}: {exc.Message}", exc);
                }
                catch (UnauthorizedAccessException exc)
                {
                    throw new SerializationException($"Unable to create directory {path}: {exc.Message}", exc);
                }
            }

            try
            {
                using(StreamWriter sw = File.CreateText(filePath))
                {
                    XmlSerializer xs = new XmlSerializer(typeof(T));
                    xs.Serialize(sw, serializationObject);
                    sw.Flush();
                    sw.Close();
                }
            }
            catch (UnauthorizedAccessException exc)
            {
                throw new SerializationException(exc.Message, exc);
            }
            catch (IOException exc)
            {
                throw new SerializationException(exc.Message, exc);
            }
            catch (InvalidOperationException exc)
            {
                throw new SerializationException(exc.Message, exc);
            }
        }

        /// <summary> serialize object to stream </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="textWriter"></param>
        /// <param name="serializationObject"></param>
        public void SerializeObject<T>(TextWriter textWriter, T serializationObject)
        {
            // check stream
            if (textWriter == null)
                throw new SerializationException("Unable to write to textwriter!");

            try
            {
                XmlSerializer xs = new XmlSerializer(typeof(T));
                xs.Serialize(textWriter, serializationObject);
                textWriter.Flush();
            }
            catch (UnauthorizedAccessException exc)
            {
                throw new SerializationException(exc.Message, exc);
            }
            catch (IOException exc)
            {
                throw new SerializationException(exc.Message, exc);
            }
            catch (InvalidOperationException exc)
            {
                throw new SerializationException(exc.Message, exc);
            }
        }


        /// <summary> deserialize from passed file  </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="filePath"></param>
        /// <returns></returns>
        /// <exception cref="SerializationException">Condition.</exception>
        public T DeserializeObject<T>(string filePath)
        {
            if (!File.Exists(filePath))
                throw new SerializationException($"File does not exist: {filePath}");

            try
            {
                using (StreamReader sr = File.OpenText(filePath))
                {
                    XmlSerializer xs = new XmlSerializer(typeof(T));
                    return (T) xs.Deserialize(sr);
                }
            }
            catch (UnauthorizedAccessException exc)
            {
                throw new SerializationException(exc.Message, exc);
            }
            catch (IOException exc)
            {
                throw new SerializationException(exc.Message, exc);
            }
            catch (InvalidOperationException exc)
            {
                throw new SerializationException(exc.Message, exc);
            }
        }

        /// <summary> deserialize from textreader </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="textReader"></param>
        /// <returns></returns>
        /// <exception cref="SerializationException">Condition.</exception>
        public T DeserializeObject<T>(TextReader textReader)
        {
            // check stream
            if (textReader == null)
                throw new SerializationException("Unable to write to stream!");

            try
            {
                    XmlSerializer xs = new XmlSerializer(typeof(T));
                    return (T)xs.Deserialize(textReader);
            }
            catch (UnauthorizedAccessException exc)
            {
                throw new SerializationException(exc.Message, exc);
            }
            catch (IOException exc)
            {
                throw new SerializationException(exc.Message, exc);
            }
            catch (InvalidOperationException exc)
            {
                throw new SerializationException(exc.Message, exc);
            }
        }
    }
}